#include "filelock.h"
#include "stream.h"
#include "pathutils.h"
#include "fileutils.h"

namespace base
{
	FileLock::FileLock(const std::string& path, FileStream* file)
		: path_(path), file_(file)
	{
	}

	FileLock::~FileLock()
	{
		MaybeUnlock();
	}

	void FileLock::Unlock()
	{
		LOG_F(LS_INFO);
		MaybeUnlock();
	}

	void FileLock::MaybeUnlock()
	{
		if (file_)
		{
			LOG(LS_INFO) << "Unlocking:" << path_;
			file_->Close();
			Filesystem::DeleteFile(path_);
			file_.reset();
		}
	}

	FileLock* FileLock::TryLock(const std::string& path)
	{
		FileStream* stream = new FileStream();
		bool ok = false;
#ifdef WIN32
		// Open and lock in a single operation.
		ok = stream->OpenShare(path, "a", _SH_DENYRW, NULL);
#else
		ok = stream->Open(path, "a", NULL) && stream->TryLock();
#endif
		if (ok)
			return new FileLock(path, stream);
		else
		{
			// Something failed, either we didn't succeed to open the
			// file or we failed to lock it. Anyway remove the heap
			// allocated object and then return NULL to indicate failure.
			delete stream;
			return NULL;
		}
	}
}